<?php
require_once 'models/discounts.inc';
require_once 'models/orm.inc';
require_once 'models/TCatalogProductModel.inc';
require_once 'models/TMSOrderModel.inc';


class TMSDiscountItem extends TCandyItem {	
	public function GetAmount(TMSProductItem $article, IItem $client = null, $points = null){
		if ($this->DiscountAmount)
			return $this->DiscountAmount;
		if ($this->AmountExpression)
			return include $this->Model->ExpressionScript($this,'AmountExpression');
		return 0;
	}
	
	public function Calculate($price,TMSProductItem $article, IItem $client = null, $points = null){
		$v = $this->GetAmount($article,$client,$points);
		if ($this->Type == TMSDiscount::DT_PERCENTAGE)
			$v = round($price*$v/100,0);
		return $v;
	}
	
	public function CanApplyToClient(IItem $client){
		if ($this->ApplyType == TMSDiscount::AT_CLIENT || $this->ApplyType == TMSDiscount::AT_ANY)
			return include $this->Model->ExpressionScript($this,'ClientCheckExpression');
		return false;
	}
	
	public function CanApplyToProduct(TMSProductItem $article){
		if ($this->ApplyType == TMSDiscount::AT_PRODUCT || $this->ApplyType == TMSDiscount::AT_ANY)
			return include $this->Model->ExpressionScript($this,'ProductCheckExpression');
		return false;
	}
	
	public function CanApplyToOrder(TMSProductItem $article, IItem $client){
		if ($this->ApplyType == TMSDiscount::AT_BOTH)
			if (include $this->Model->ExpressionScript($this,'ClientCheckExpression'))
				return include $this->Model->ExpressionScript($this,'ProductCheckExpression');
		return false;
	}
	
	public function PointsIncrement(TMSOrderItem $order, $points){
		if ($this->DiscountPoints)
			return $this->DiscountPoints*$order->Amount;
		if ($this->PointsIncrementExpression)
			return include $this->Model->ExpressionScript($this,'PointsIncrementExpression');
		return 0;
	}
	
	public function PointsDecrement(TMSOrderItem $order, $points, $discount_amount){
		if ($this->PointsDecrementExpression)
			return include $this->Model->ExpressionScript($this,'PointsDecrementExpression');
		return $discount_amount;
	}
}


class TMSDiscountModel extends TCandyModel {
	protected $_conf_script_path_;
	
	private $_implicit_product_discounts_;
	
	private $_implicit_client_discounts_;
	
	public function __set($nm,$value){
		switch ($nm){
			case 'ScriptPath':$this->_conf_script_path_ = $this->Application()->AdjustPath($value);break;
			default:parent::__set($nm,$value);break;
		}	
	}
	
	public function __get($nm){
		switch ($nm){
			case 'ScriptPath':{
				if (is_null($this->_conf_script_path_))
					$this->_conf_script_path_ = $this->Application()->PrivateDir().'/discounts';
				return $this->_conf_script_path_;
			}break;
			default:return parent::__get($nm);break;
		}
	}
	
	protected function afterConstruct(){
		$this->_conf_classname_ = 'TMSDiscount';
	}
	
	protected function postProcessProperties(){
		parent::postProcessProperties();
		$this->propertyMetas['Type']->SetSelection(array(
					TMSDiscount::DT_PERCENTAGE => "Percent",
					TMSDiscount::DT_ABSOLUTE => "Absolute"
				));
		$this->propertyMetas['ApplyRule']->SetSelection(array(
					TMSDiscount::AT_CLIENT => "Apply by client",
					TMSDiscount::AT_PRODUCT => "Apply by product",
					TMSDiscount::AT_ANY => "Apply by client or product",
					TMSDiscount::AT_BOTH => "Apply by client and product"
				));
		
		$this->propertyMetas['AmountExpression']->Type = TItemPropertyType::PT_MULTILINE;
		$this->propertyMetas['ClientCheckExpression']->Type = TItemPropertyType::PT_MULTILINE;
		$this->propertyMetas['ProductCheckExpression']->Type = TItemPropertyType::PT_MULTILINE;
		$this->propertyMetas['PointsIncrementExpression']->Type = TItemPropertyType::PT_MULTILINE;
		$this->propertyMetas['PointsDecrementExpression']->Type = TItemPropertyType::PT_MULTILINE;
	}
	
	public function ExpressionScript(IItem $discount,$name){
		$script = $this->ScriptPath.'/'.$name.'_'.$discount->ItemId().'.php';
		if (!file_exists($script))
			file_put_contents($script, "<?php\n".$discount->$name);
		return $script;
	}
		
	protected function postEditItem(TCandyItem $item, $origin, array $data = array()){
		if ($item->AmountExpression != $origin->AmountExpression)
			unlink($this->ScriptPath.'/AmountExpression_'.$item->ItemId().'.php');
		if ($item->ClientCheckExpression != $origin->ClientCheckExpression)
			unlink($this->ScriptPath.'/ClientCheckExpression_'.$item->ItemId().'.php');
		if ($item->ProductCheckExpression != $origin->ProductCheckExpression)
			unlink($this->ScriptPath.'/ProductCheckExpression_'.$item->ItemId().'.php');
		if ($item->PointsIncrementExpression != $origin->PointsIncrementExpression)
			unlink($this->ScriptPath.'/PointsIncrementExpression_'.$item->ItemId().'.php');
	}

	public function ProductApplicableDiscounts(){
		return $this->GetList(new TListOptions(array(new TFilterOption('ApplyRule', TConditionType::C_NOT_EQUAL, TMSDiscount::AT_CLIENT),new TFilterOption('IsActive', TConditionType::C_EQUAL, true))));
	}
	
	public function ImplicitProductDiscounts(){
		if (!$this->_implicit_product_discounts_){
			$this->_implicit_product_discounts_ = array();
			$temp = $this->GetList(new TListOptions(array(
					new TFilterOption('ApplyRule', TConditionType::C_NOT_EQUAL, TMSDiscount::AT_CLIENT),
					new TFilterOption('IsActive', TConditionType::C_EQUAL, true),
					new TFilterOption('ProductCheckExpression',TConditionType::C_NOT_EQUAL,null)
				)));
		}
		return $this->_implicit_product_discounts_;
	}
	
/**
 * @param object $object
 * @return TCandyItem
 */
	public function WrapObject($object, array &$caller_stack = array()){
		if ($object instanceof $this->_conf_classname_)
			return new TMSDiscountItem($object,$this);
		return parent::WrapObject($object,$caller_stack);
	}
	
}